#!/usr/bin/python

import os;

#Kernel_Dir is the directory name of kernel
Kernel_Dir="./kernel/";
Lib_Dir="./lib/";
sourceDirSet=list();
sourceDirSet.append(Kernel_Dir);
sourceDirSet.append(Lib_Dir);
#Include_Dir is the directory name of the include directory
Include_Dir="./include/";
#parameters is the parameters for "gcc -M"
parameters=" -I "+Include_Dir;
parameters=" -I "+Kernel_Dir+Include_Dir;

#get the -I option parameters for "gcc -M"
include_dirs_set=os.listdir(Include_Dir);#include_dirs_set is the names set of all files under Include_Dir
for d_file in include_dirs_set:
	ddir=Include_Dir+d_file
	if os.path.isdir(ddir):
		parameters+=" -I "+ddir;
#get the dependency relations of kernel & lib .c and .asm files
#cFileRuleSet is the list for the c file rules
#asmFileRuleSet is the list for the assemble file rules
tmpFile="./mk.tmp"
cFileRuleSet=list();
asmFileRuleSet=list();
objFiles="";
for sourceDir in sourceDirSet:
	kernel_files_set=os.listdir(sourceDir);
	for c_file in kernel_files_set:
		filePath=sourceDir+c_file;
		if os.path.isfile(filePath):
			#deal with c source file
			if filePath.endswith(".c"):
				#get object File name
				objectFile=filePath.replace(".c",".o");
				objFiles+=objectFile+" ";
				#generate c object file rule,via "gcc -M" command option
				#the command result is first written into "tmpFile" file,then the content is read out
				#!!!Because the generated object file name doesn't include parent folder name,So it must be 
				#added to the rule manually
				cmd="gcc -M "+filePath+parameters+" > "+tmpFile;
				ret=os.system(cmd);
				if ret!=0:
					print "gcc -M error"
				else:
					rule=sourceDir;#the parent folder name is added here to the rule
					f=file(tmpFile,"r");
					tmp=f.readline()
					while tmp!="":
						rule+=tmp;
						tmp=f.readline();
					rule+="\t$(CC) $(CFLAGS) -o $@ $<\n"
					cFileRuleSet.append(rule);
			#deal with assemble source file
			elif filePath.endswith(".asm"):
				#get object File name
				objectFile=filePath.replace(".asm",".o");
				if filePath.endswith("kernel.asm")==False:
					objFiles+=objectFile+" ";
				#generate asm object file rule
				rule=objectFile+": "+filePath;
				if c_file=="kernel.asm":
					rule+=" include/pm.inc";#kernel.asm needs "pm.inc" file
				rule+="\n\t$(ASM) $(ASM_KERNEL_FLAGS) -o $@ $<\n"
				asmFileRuleSet.append(rule);
#delete temporary file
os.system("rm -f "+tmpFile);
#generate "OBJS" variable
objFiles="OBJS=./kernel/kernel.o "+objFiles+"\n"
#
MakeFileName="./makefile"
basefile_1="./config/m1_base";
basefile_2="./config/m2_base";
basefile_3="./config/m3_base";

#generate makefile
os.system("cp -f "+basefile_1+" "+MakeFileName);
f=file(MakeFileName,"a");
f.write(objFiles);
f.write("CFLAGS=-c -fno-builtin -m32 -fno-stack-protector -Wno-deprecated "+parameters);#"CFLAG" variable must be modified
f.close();
os.system("cat "+basefile_2+" >> "+MakeFileName);
os.system("cat "+basefile_3+" >> "+MakeFileName);
f=file(MakeFileName,"a");
for s in cFileRuleSet:
	f.write(s);
for s in asmFileRuleSet:
	f.write(s);
f.close();

